iT邦幫忙

2026 iThome 鐵人賽

DAY 19
0
AI Engineering

不是模型太慢,是你沒算過這筆帳:地端 LLM 工程實戰 30 天系列 第 19

Day 19 - 1,792 GB/s 的 5090 對 1,200 GB/s 的 M5 Ultra:為什麼帳面 decode 上界只差 6%?

  • 分享至 

  • xImage
  •  

https://ithelp.ithome.com.tw/upload/images/20260830/20183550bp44dzEnWZ.png

同一份 100 頁 PDF、同一個問題,丟給地端模型要等一兩分鐘,送到雲端幾秒就開始回答。最常聽到的解釋是「雲端 GPU 比較快」。

這句沒錯,但太粗,粗到不能拿來買機器。

因為一次請求至少是兩本帳:把你的文件讀進去(prefill),跟一個字一個字吐出來(decode)。兩本帳吃的硬體不一樣,所以同一台機器可以 prefill 很強、decode 很弱;規格表上漂亮的那個數字,未必是決定你等多久的那一個。

今天把 2026 買得到的七台機器攤開,用規格表算一次——然後看它算得出什麼、算不出什麼。

📌 勘誤day05.md 說「格式天梯我們第 19 天爬」、day09.md 說「Day 19 接上儀表板」,這兩件事都挪到後面的篇章,今天不談。

七種推論硬體的底盤

先看規格,不看排名。容量與頻寬都取官方頁:

機器 記憶體 頻寬 買它是為了什麼
Mac Studio M5 Ultra 512GB 512 GB 1,200 GB/s 桌面單機容量,這張表沒有對手
Mac Studio M5 Max 128GB 128 GB 614 GB/s 安靜、省電、放得下
DGX Spark GB10 128 GB 273 GB/s CUDA 生態 + 統一記憶體
RTX 5090 32 GB 1,792 GB/s 消費級單卡的單流速度
RTX PRO 6000 Blackwell 96 GB 1,792 GB/s 速度與容量兼顧
H100 SXM 80 GB 3,350 GB/s 高 batch
B200 SXM 180 GB 8,000 GB/s 長 context + 高吞吐

兩個買之前會後悔的細節:RTX PRO 6000 有三個版本,Server Edition 只有 1,597 GB/s,比 Workstation 低 11%;M5 Max 的 614 GB/s 是 40 核 GPU 版,32 核版是 460。帳面 decode 上界直接正比於頻寬,買錯版本,這一階估算就樂觀一成。

規格表算得出 decode 的帳面上界

單流 decode 每吐一個 token,權重就要被讀過一次。所以:

tok/s 上界 ≈ 記憶體頻寬(GB/s)÷ 每個 step 要讀的權重(GB)

分母是「每個 step 要讀的權重」,不是「模型檔多大」。這兩件事只在幾個條件同時成立時才夠接近:bs=1、dense、關掉 MTP 與投機解碼、text decode 幾乎碰到檔內所有權重、記憶體內格式跟檔案格式差不多。

下面拿 checkpoint 大小當那個分母的 proxy——它是第一版 roofline,不是物理硬牆。用途是幫你對 benchmark 做 sanity check。

尺用 Qwen3.8-27B,權重取各平台實際載入的那一份。檔案大小從 HF 的 ?blobs=true 取得,只加總 runtime 真的會載入的那組 weight shards——同一個 repo 裡常有第二份權重或 MTP 模組(這份 NVFP4 就另外放了 849 MB 的 model_mtp.safetensors),無條件全加會得到假數字。⚠️ NVFP4 是 Blackwell 原生格式,Hopper 只到 FP8,所以 H100 那列走的是官方 FP8 檔:

機器 跑哪一份 權重 帳面上界
Mac Studio M5 Ultra MLX-4bit 16.05 GB 74.7
Mac Studio M5 Max MLX-4bit 16.05 GB 38.2
DGX Spark GB10 NVFP4 22.57 GB 12.1
RTX 5090 NVFP4 22.57 GB 79.4
RTX PRO 6000 NVFP4 22.57 GB 79.4
H100 SXM FP8 30.87 GB 108.5
B200 SXM NVFP4 22.57 GB 354.5

https://ithelp.ithome.com.tw/upload/images/20260830/20183550mt86Q0312W.png
圖 1:容量與頻寬是兩條獨立的軸——沒有一台兩邊都拿滿,而右欄那個上界還會被「跑哪一份檔」再改一次。

上界是算出來的,實際跑到多少是量出來的。Day 10 在自己兩台機器上量過同一條除法的兌現率:Metal 52%、CUDA 80%,而且那篇自己就聲明過不該當成固定常數。所以上面那欄要讀成「同一組前提下,大概落在它的一半到八成五」。

標題那個 6% 是怎麼來的

看第一列跟第四列:M5 Ultra 的頻寬是 1,200,RTX 5090 是 1,792,差 49%。但帳面上界 74.7 對 79.4,只差 6%。這個 6% 只存在於「頻寬 ÷ checkpoint 大小」這組 proxy 裡,不代表兩台實測也只差 6%——它要說明的是,分母差 41% 足以吃掉大部分的頻寬優勢。

差額被同一個東西吃掉了:兩邊跑的「4-bit」根本不是同一份檔。

MLX-4bit   16.05 GB → 0.58 bytes/param
NVFP4      22.57 GB → 0.81 bytes/param   大 41%

原因不神祕:「4-bit」不代表每個 tensor 都是 4-bit。不同 exporter 保留的模組不一樣——這份 NVFP4 的 config.json 有一長串 ignorelm_head 還是 FP8。**把兩個檔案大小代進同一個 1,792 GB/s 的分子,算式會得到 112 對 79。**這是隔離「分母大小」影響的紙上比較——MLX 的 checkpoint 並不能直接丟到 NVIDIA runtime 上跑,所以它不是同卡可實跑的 A/B。

https://ithelp.ithome.com.tw/upload/images/20260830/20183550hU0p2jCMJZ.png
圖 2:買 Blackwell 買的是 FP4 算力,但不同 exporter 保留的模組不同,先把帳面上界吃掉三成。

所以規格表上的頻寬不能單獨看。要看的是「頻寬 ÷ 你這一步實際要讀的東西」。第一階 proxy 就是 runtime 會載入的 weight shards 有多大,?blobs=true 查得到這個分母;至於每一步真正產生多少 HBM traffic,還是得看執行路徑或 profiler。

順手用這條除法審一個網傳數字

DGX Spark 那格的帳面上界是 12.1 tok/s。而網路上流傳的同一顆模型、同一台機器的 decode 實測是 29.2。

高出 2.4 倍。這還不足以判它死刑——上界是拿整包 checkpoint 大小當分母算的,分母本來就可能高估。但它足以讓你知道要去問四件事:

  1. 有沒有開 MTP/投機解碼?Qwen3.8-27B 自己就帶 MTP head,這是第一個要查的。
  2. 那個 tok/s 算的是被接受的 output token,還是 target model 的 step 數?
  3. 22.57 GB 裡有多少 tensor 在 text decode 真的被讀到?
  4. 是不是換了另一份量化檔、或另一種記憶體內表示?

這是我看地端 benchmark 的第一動作:先用規格算一次上界,再看那個數字要靠什麼才站得住。

這條除法還有第二個破口:MoE

上面整套推算有個沒說的前提:每吐一個 token,整份權重都要被讀過一次。純文字的 dense backbone 在單流 decode 下大致接近這個前提,MoE 不是。

Qwen3.6-35B-A3B 來看。它的 MLX-4bit 檔是 20.40 GB,比 27B dense 的 16.05 GB 大 27%;照除法,M5 Ultra 上的帳面上界應該從 74.8 掉到 58.8。

但它每個 token 只啟用 3B 參數,佔總量的 8.3%。58.8 只是「把所有 expert 都當成每步都讀」算出來的保守 roofline,既不是實際上限,也不是速度下限——真實值可能高於它(讀的 byte 少很多),也可能低於它(routing、gather 與 kernel 利用率都要錢)。落在哪,只能量。

順帶它的 KV 反而更省:每 token 20,480 bytes,比 27B dense 的 32,768 少 38%(40 層裡只有 10 層是 full attention)。

所以「35B 一定比 27B 慢」是錯的。模型架構本身就能把硬體排行榜翻過來,而分母寫「模型檔多大」的那一刻,這件事就已經被算錯了。

規格表算不出 prefill

到這裡為止,規格表都很好用。然後就沒了。

prefill 是把幾千幾萬個 token 疊成大矩陣一起算,同一份權重被大量重用,瓶頸從記憶體頻寬移到矩陣算力、低精度 kernel 與 attention 實作。這三樣沒有一樣能從「GB 與 GB/s」兩欄推出來。

具體有多不能推?Day 13 在三台機器上跑過同一顆模型、同一個 llama-bench:decode 兩台打平(59.64 對 59.27),prefill 差到八倍(819 對 6,556)。頻寬 546 對 504,幾乎一樣。

**這張只列 GB 與 GB/s 的規格表,能告訴你 decode 大概在哪;prefill 的實際速度仍得量。**而 100 頁 PDF 那種 workload,決定你等多久的偏偏是 prefill。

那到底哪一段在等?

prefill 與 decode 花一樣久的時候:

N_input / PP = N_output / TG   →   N_output* = N_input × TG / PP

實際輸出超過 N_output* 就是 decode 主導,低於就是 prefill 主導。代三組數字看看:

PP / TG 比值 60K input 的分界
600 / 40(地端 Mac 常見量級) 15 4,000 output tokens
2,250 / 29(DGX Spark 量級) 78 773
9,900 / 62(Blackwell 工作站量級) 160 376

同一份 60K input、輸出 500 個 token,三列的秒數是這樣:

PP / TG prefill decode 誰主導
600 / 40 100.0 s 12.5 s prefill 89%
2,250 / 29 26.7 s 17.2 s prefill 61%
9,900 / 62 6.1 s 8.1 s decode 57%

第一列幾乎九成時間都在 prefill;到了第三列,prefill 只剩 6 秒,反而是 8 秒的 decode 稍微主導。PP 相對 TG 拉得越快,分界線越往下掉,輸出就越容易超過它,越多 workload 轉成 decode-bound

https://ithelp.ithome.com.tw/upload/images/20260830/20183550BpIkkKHyTq.png
圖 3:context 一長,帳面上界自己會被 KV 吃掉——256K 時 KV 已經佔每個 step 讀取量的 27.6%。

而且這個上界本身也不是常數。同一台 RTX PRO 6000,context 從 0 拉到 256K,KV 從佔 0% 長到 27.6%,上界從 79.4 掉到 57.5。長 context 是兩頭都吃:prefill 變慢,decode 也跟著鈍。

回到開場:雲端那幾秒是怎麼回事

現在可以回答開頭那個 100 頁 PDF 了。雲端贏的可能根本不是硬體。

最常見的一種是:雲端那套先做了 chunk、檢索與重排,最後只送 8–15K 進模型;你的地端程式把整份 60K 硬塞。就算兩邊 prefill 速度一模一樣,60K ÷ 10K = 6 倍,雲端照樣快六倍。

所以「同一份 PDF」不是可比的條件。要比,至少要記下雙邊實際的 prompt_tokenscached_tokenscompletion_tokens——不然你以為在比機器,其實在比誰送的 token 少。

買機器該問的四個數字

規格表回答不了「這台跑幾 tok/s」,因為那是錯的問題。對的問題是四個:

  1. 平均 input 幾 K? 決定 prefill 那段的長度。
  2. 平均 output 幾 K? 跟前一項一起決定你落在分界線的哪一邊。
  3. cold prefix 佔多少? 能不能重用前一輪,差距是一整段 prefill。
  4. 同時幾個人在 decode? 單流上界跟聚合吞吐是兩本帳。

拿這四個數字回頭看那張底盤表,選擇會突然變得很清楚:

你的 workload 先看哪一欄 容易看錯的
客服 FAQ、一般 chat 聚合 decode 吞吐 單流 prefill
企業 RAG(8–40K) cold prefill / TTFT 單流 tok/s
整份文件 QA(30K+) prefill 只看記憶體大小
Coding autocomplete prefill + 前綴重用 decode 峰值
長 reasoning / thinking decode 最大 context
128K 以上 長 context prefill + KV 頻寬 8K 的 TPS

小結

  • 規格表只算得出 decode 的帳面上界(頻寬 ÷ 每步要讀的權重),而 checkpoint 大小只是那個分母的第一階近似——prefill 那一欄,規格表回答不了。
  • **同樣叫 4-bit,NVFP4 比 MLX-4bit 大 41%。**所以頻寬差 49% 的兩台機器,帳面 decode 上界可以只差 6%。
  • 看到超過上界的 benchmark,先問它多開了什麼:MTP/投機解碼、另一份量化檔、或 tok/s 的分子根本不是同一個東西。

今天的實驗需要什麼

不用機器,一張紙就夠:去 HF 用 ?blobs=true 查檔案大小,依 weight index 加總 runtime 真正會載入的 shards,除以你那台的帳面頻寬,得到第一版上界。再拿你自己量過的 tok/s 除以它,就是這個模型、這份量化、這個 runtime、這個 context 下的兌現率——之後比較相近配置時可以拿它當 baseline,不能跨模型、跨 runtime 當固定常數

明天 Day 20 換一個角度:機器買回來之後,一張卡要同時養 LLM、embedding、reranker 三張嘴,該怎麼切。

咱們明天見。


上一篇
Day 18 - 只換一行位置,15.7 秒變 0.2 秒:你的 prompt 為什麼一直重算?
下一篇
Day 20 - 接受率 1.00,為什麼反而輸給 0.94?投機解碼不是猜準就會快
系列文
不是模型太慢,是你沒算過這筆帳:地端 LLM 工程實戰 30 天25
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言